//
// Created by delin10 on 2020/5/2.
//

#include <stdlib.h>
#include <fcntl.h>
#include "sock_utils.h"
#include "net_utils.h"
#include "../debug.h"

/**
 * 创建一个TCP socket
 * @return socket描述符
 */
int create_tcp_sock() {
    int sock_fd = socket(AF_INET, SOCK_STREAM, 0);
    return sock_fd;
}


static char* open_server_socket_fmt = "Failed to %s at phrase: %s";
char* phrases[] = {"create tcp sock", "to_ip_sockaddr_in", "bind", "listen", "", "", "", "", "", "",
                   /*index = 10*/"create tcp sock", "to_ip_sockaddr_in", "connect"};

#define OPEN_OP "open server socket"
#define CONNECT_OP "connect server socket"

#define LOG_PHRASE_ERROR(op, p) \
    d_log_err(open_server_socket_fmt, op, phrases[*p]);\
    return -1;

int open_server_socket(char *bind_addr, int port) {
    int fd = create_tcp_sock();
    int phrase = 0;
    if (fd < 0) {
        LOG_PHRASE_ERROR(OPEN_OP, &phrase);
    }
    phrase++;
    struct sockaddr *addr = (struct sockaddr *) to_ip_sockaddr_in(bind_addr, port);
    if (addr == NULL) {
        LOG_PHRASE_ERROR(OPEN_OP, &phrase);
    }
    phrase++;
    if (bind(fd, addr, sizeof(struct sockaddr_in)) < 0) {
        LOG_PHRASE_ERROR(OPEN_OP, &phrase);
    }
    phrase++;
    if (listen(fd, SOMAXCONN) < 0) {
        LOG_PHRASE_ERROR(OPEN_OP, &phrase);
    }
    return fd;
}

int connect_to_tcp_server(char *ip, int port) {
    int fd = create_tcp_sock();
    int p = 10;
    if (fd < 0) {
        LOG_PHRASE_ERROR(CONNECT_OP, &p);
    }
    p++;
    struct sockaddr *addr = (struct sockaddr *) to_ip_sockaddr_in(ip, port);
    if (addr == NULL) {
        LOG_PHRASE_ERROR(CONNECT_OP, &p);
    }
    p++;
    if (connect(fd, addr, sizeof(struct sockaddr)) < 0) {
        LOG_PHRASE_ERROR(CONNECT_OP, &p);
    }
    return fd;
}

int setnonblocking(int sock){
    int opts;
    opts=fcntl(sock,F_GETFL);
    if(opts<0)
    {
        return 0;
    }
    opts = opts|O_NONBLOCK;
    if(fcntl(sock,F_SETFL,opts)<0)
    {
        return 0;
    }
    return 1;
}